package oojo.data.impl.exec.sub;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import oojo.data.spec.Fetch;
import oojo.data.spec.sub.SubFetch;
import oojo.data.impl.Properties;
import oojo.data.impl.SubRepositoryImpl;
import oojo.data.impl.exec.FetchQuery;

public class SubFetchQuery<E> extends FetchQuery<E> {

    private static final Logger logger = LoggerFactory.getLogger(SubFetch.class);
    
    public Class<?> getQueryClass() {
        return SubFetch.class;
    }
    
    protected String createFrom(Fetch<E> fetch) {
        logger.debug("---> createFrom(fetch)");
        
        SubFetch<E> spec = (SubFetch<E>) fetch;
        
        if (spec.getParentId() != null) {
            SubRepositoryImpl<E> repository = (SubRepositoryImpl<E>) getRepository();
            
            if (repository.getParentProperty() != null) {
                return "from " + repository.getEntityClass().getName() + " e join e." + repository.getParentProperty() + " m";   
            } else if (repository.getChildsProperty() != null) {
                return "from " + repository.getParentClass().getName() + " m join m." + repository.getChildsProperty() + " e";  
            }
        }
        
        return super.createFrom(spec);
    }
    
    protected String createCriteria(Fetch<E> fetch) {
        logger.debug("---> createCriteria(fetch)");
        
        SubFetch<E> spec = (SubFetch<E>) fetch;
        String sc = super.createCriteria(spec);
        
        if (spec.getParentId() != null) {
            SubRepositoryImpl<E> repository = (SubRepositoryImpl<E>) getRepository();
            String parentIdProperty = Properties.idProperty(repository.getParentClass());
            StringBuilder sb = new StringBuilder().append("m.").append(parentIdProperty).append(" = :parentId");
            
            if (sc != null) {
                sb.append(" and (").append(sc).append(")");
            }
            
            return sb.toString();
        }
        
        return sc;
    }
    
    protected void configCriteria(Fetch<E> fetch, javax.persistence.Query query) {
        logger.debug("---> configCriteria(fetch, query)");
        
        SubFetch<E> spec = (SubFetch<E>) fetch;
        
        if (spec.getParentId() != null) {
            query.setParameter("parentId", spec.getParentId());
        }
        
        super.configCriteria(spec, query);
    }
}
